﻿using Microsoft.WindowsAPICodePack.ApplicationServices;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using WeighClient.Model;
using WeighClient.Utils;
using WeighClient.Windows;

namespace WeighClient
{
    /// <summary>
    /// App.xaml 的交互逻辑
    /// </summary>
    public partial class App : Application
    {
        public static DeviceInfo deviceInfo = null;
        private static object _lock = new object();

        public static HttpServer httpServer = null;
        private static object _httpLock = new object();

        public static Config config = null;
        public static RunTimeVariable runTimeVariable = null;
        public static GlobalVariablesModel globalVariables = null;
        /// <summary>
        /// 主进程互斥量
        /// </summary>
        private static System.Threading.Mutex mutex_main;

        /// <summary>
        /// 守护进程互斥量
        /// </summary>
        private static System.Threading.Mutex mutex_deamon;

        /// <summary>
        /// 是否为主进程
        /// </summary>
        private static bool isMain = false;

        /// <summary>
        /// 打开监视定时器
        /// </summary>
        public void RunMonitorTimer()
        {
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Elapsed += timer_Elapsed;
            timer.Interval = 2000;
            timer.Start();
        }
        /// <summary>
        /// 打开程序
        /// </summary>
        /// <param name="arg">参数不为null时打开主进程，否则打开守护进程</param>
        public void RunProcess(string arg = null)
        {
            /* 运行程序，不带参数，打开守护进程 */
            Process m_Process = new Process();
            m_Process.StartInfo.FileName = Process.GetCurrentProcess().MainModule.FileName;
            m_Process.StartInfo.Arguments = arg;
            m_Process.Start();

        }

            public static DeviceInfo GetDeviceInfo()
        {
            if (deviceInfo == null)
            {
                lock (_lock)
                {
                    if (deviceInfo == null)
                    {
                        deviceInfo = new DeviceInfo();
                    }
                }
            }
            return deviceInfo;
        }
        public static Config GetConfig()
        {
            if (config == null)
            {
                lock (_lock)
                {
                    if (config == null)
                    {
                        config = new Config();
                    }
                }
            }
            return config;
        }
        public static RunTimeVariable GetRunTimeVariable()
        {
            if (runTimeVariable == null)
            {
                lock (_lock)
                {
                    if (runTimeVariable == null)
                    {
                        runTimeVariable = new RunTimeVariable();
                    }
                }
            }
            return runTimeVariable;
        }

        public static HttpServer GetHttpServer()
        {
            if (httpServer == null)
            {
                lock (_httpLock)
                {
                    if (httpServer == null)
                    {
                        int port = int.Parse(App.GetConfig().LocalHttpServerPort);
                        httpServer = new HttpServer(port);
                    }
                }
            }
            return httpServer;
        }
        public static GlobalVariablesModel getGlobalVariables()
        {
            if (globalVariables == null)
            {
                lock (_lock)
                {
                    if (globalVariables == null)
                    {
                        globalVariables = new GlobalVariablesModel();
                    }
                }
            }
            return globalVariables;
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            //

            //根据参数判断开启主进程还是守护进程，守护进程不带参数，主进程带参数
            //if (e.Args.Length < 1)
            //{
            //    Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;

            //    //守护进程互斥量
            //    mutex_deamon = new System.Threading.Mutex(true, "MUTEX_DEAMON");
            //    if (mutex_deamon.WaitOne(0, false))
            //    {
            //        RunMonitorTimer();

            //        // 显示一个自定义窗体，非主窗体，用于阻塞进程，窗体关闭后，守护进程将关闭
            //        WndDeamon wnd = new WndDeamon();
            //        wnd.ShowDialog();

            //        this.Shutdown();
            //    }
            //    else
            //    {
            //        MessageBox.Show("程序已经在运行！", "提示");
            //        this.Shutdown();
            //    }
            //}
            //else
            //{
            //    isMain = true;
            //    mutex_main = new System.Threading.Mutex(true, "MUTEX_MAIN");
            //    if (mutex_main.WaitOne(0, false))
            //    {
            //        RunMonitorTimer();

            //        base.OnStartup(e);
            //        Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
            //    }
            //    else
            //    {
            //        Application.Current.ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;
            //        MessageBox.Show("程序已经在运行！", "提示");
            //        this.Shutdown();
            //    }
            //}


            App.GetConfig().DeviceCode = ConfigurationManager.AppSettings["DeviceCode"];
            App.GetConfig().DeviceName = ConfigurationManager.AppSettings["DeviceName"];
            App.GetConfig().DeviceType = ConfigurationManager.AppSettings["DeviceType"];

            App.GetConfig().IC_Card_PortName = ConfigurationManager.AppSettings["IC_Card_PortName"];

            App.GetConfig().IO_Com_PortName = ConfigurationManager.AppSettings["IO_Com_PortName"];
            App.GetConfig().IO_In_Open_Port = ConfigurationManager.AppSettings["IO_In_Open_Port"];
            App.GetConfig().IO_In_Close_Port = ConfigurationManager.AppSettings["IO_In_Close_Port"];
            App.GetConfig().IO_Out_Open_Port = ConfigurationManager.AppSettings["IO_Out_Open_Port"];
            App.GetConfig().IO_Out_Close_Port = ConfigurationManager.AppSettings["IO_Out_Close_Port"];

            App.GetConfig().IO_In_Input_Port = ConfigurationManager.AppSettings["IO_In_Input_Port"];
            App.GetConfig().IO_Out_Input_Port = ConfigurationManager.AppSettings["IO_Out_Input_Port"];

            App.GetConfig().HttpServerIp = ConfigurationManager.AppSettings["HttpServerIp"];
            App.GetConfig().HttpServerPort = ConfigurationManager.AppSettings["HttpServerPort"];
            App.GetConfig().IDCard = ConfigurationManager.AppSettings["IDCard"];
            App.GetConfig().IDCardPort1 = ConfigurationManager.AppSettings["IDCardPort1"];
            App.GetConfig().IDCardPortBaudRate = ConfigurationManager.AppSettings["IDCardPortBaudRate"];
            App.GetConfig().IDCardIP = ConfigurationManager.AppSettings["IDCardIP"];

            App.GetConfig().LocalHttpServerPort = ConfigurationManager.AppSettings["LocalHttpServerPort"];
            App.GetConfig().IDCardNumber = ConfigurationManager.AppSettings["IDCardNumber"];

            App.GetConfig().Mq_HostName = ConfigurationManager.AppSettings["Mq_HostName"];
            App.GetConfig().Mq_UserName = ConfigurationManager.AppSettings["Mq_UserName"];
            App.GetConfig().Mq_Password = ConfigurationManager.AppSettings["Mq_Password"];

            App.GetConfig().SteadySeconds = int.Parse(ConfigurationManager.AppSettings["SteadySeconds"]);
            App.GetConfig().WeighDifference = double.Parse(ConfigurationManager.AppSettings["Weigh_Difference"]);

            App.GetConfig().MaxWeigh = double.Parse(ConfigurationManager.AppSettings["Max_Weigh"]);

            App.GetConfig().NodeRedUrl = ConfigurationManager.AppSettings["NodeRed_URL"];
            App.GetConfig().IfPrint = ConfigurationManager.AppSettings["IfPrint"];
            App.GetConfig().RFID_iReaderPoint = ConfigurationManager.AppSettings["RFID_iReaderPoint"];
            App.GetConfig().RFID_sReaderIP = ConfigurationManager.AppSettings["RFID_sReaderIP"];
            App.GetConfig().LED_IP = ConfigurationManager.AppSettings["LED_IP"];
            App.GetConfig().Remote_Print_QueueName = ConfigurationManager.AppSettings["Remote_Print_QueueName"];
            
            string _autoWeigh = ConfigurationManager.AppSettings["AutoWeigh"];
            if ("true".Equals(_autoWeigh))
            {
                App.GetConfig().AutoWeigh = true;
                App.GetRunTimeVariable().AutoWeigh = true;
            }
            else
            {
                App.GetConfig().AutoWeigh = false;
                App.GetRunTimeVariable().AutoWeigh = false;
            }

            App.GetConfig().Weight_Comm_PortName = ConfigurationManager.AppSettings["Weight_Comm_PortName"];

            HttpServer server = App.GetHttpServer();
            if (!server.IsListening())
            {
                server.Run();
            }
            //ApplicationRestartRecoveryManager.RegisterForApplicationRestart(new RestartSettings("restart", RestartRestrictions.None));
            LogObject.WriteLog("系统启动完成!");
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;
        }

        public App()
        {
            //DispatcherUnhandledException += App_DispatcherUnhandledException;
        }

        void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            LogObject.WriteLog("系统异常------------------" + Environment.NewLine + e.Exception.Message + "--------------------------");
            //MessageBox.Show("Error encountered! Please contact support." + Environment.NewLine + e.Exception.Message);
            e.Handled = true;
        }
        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (!isMain)
            {
                if (mutex_main == null)
                {
                    mutex_main = new System.Threading.Mutex(true, "MUTEX_MAIN");
                }
                if (mutex_main.WaitOne(0, false))
                {
                    //必须释放mutex，否则将导致mutex被占用，主程序不能允许
                    mutex_main.Dispose();
                    mutex_main = null;

                    RunProcess("main");
                }
            }
            else
            {
                if (mutex_deamon == null)
                {
                    mutex_deamon = new System.Threading.Mutex(true, "MUTEX_DEAMON");
                }
                if (mutex_deamon.WaitOne(0, false))
                {
                    mutex_deamon.Dispose();
                    mutex_deamon = null;

                    RunProcess();
                }
            }
        }

    }
}
